﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BPM.Entity;
using BPM.Common;

namespace BPM.Service
{
	public static class SF
	{
		public static ServiceBase<TEntity> Create<TEntity>()
			where TEntity : BaseEntity, new()
		{
			return Create(typeof(TEntity)) as ServiceBase<TEntity>;
		}

		public static ServiceBase Create(Type entityType)
		{
			return ServiceFactory.Instance.Create(entityType);
		}

		public static TService Concreate<TService>()
			where TService : ServiceBase, new()
		{
			return new TService();
		}
	}

	public class ServiceFactory : ILazyProviderFactory
	{
		public static readonly ServiceFactory Instance = new ServiceFactory();

		private ServiceFactory() { }

		private IDictionary<Type, ServiceBase> _all = new SortedDictionary<Type, ServiceBase>(TypeComparer.Instance);

		public ServiceBase Create(Type entityType)
		{
			ServiceBase result = null;

			if (!this._all.TryGetValue(entityType, out result))
			{
				lock (this._all)
				{
					if (!this._all.TryGetValue(entityType, out result))
					{
						result = this.CreateService(entityType);
						this._all[entityType] = result;
					}
				}
			}

			return result;
		}

		/// <summary>
		/// 基于命名约定构造无状态的服务
		/// </summary>
		/// <param name="entityType"></param>
		/// <returns></returns>
		private ServiceBase CreateService(Type entityType)
		{
			var svcName = entityType.Name + "Service";
			var type = this.GetType().Assembly.GetTypes().First(t => t.Name == svcName);
			return Activator.CreateInstance(type) as ServiceBase;
		}

		#region ILazyProviderFactory Members

		ILazyProvider ILazyProviderFactory.Create(Type entityType)
		{
			return Create(entityType);
		}

		#endregion
	}
}
